package com.aos.erp.manager.rest;

import com.aos.erp.common.GlobalConstant;
import com.aos.erp.common.bean.PageBean;
import com.aos.erp.common.bean.ResultEntity;
import com.aos.erp.common.exception.BizException;
import com.aos.erp.common.utils.DateUtils;
import com.aos.erp.common.utils.StringUtils;
import com.aos.erp.manager.model.review.*;
import com.aos.erp.manager.model.review.vo.ReviewConditionVo;
import com.aos.erp.manager.model.sys.dto.UserDto;
import com.aos.erp.manager.remote.model.StudentFileInfo;
import com.aos.erp.manager.remote.model.StudentInfo;
import com.aos.erp.manager.remote.model.vo.ExportStudentConditionVo;
import com.aos.erp.manager.service.StudentReviewService;
import com.aos.erp.manager.util.ExcelData;
import com.aos.erp.manager.util.ExcelUtil;
import com.aos.erp.manager.util.UserUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

@Slf4j
@Api(tags = {"UI接口：导入导出接口"})
@RestController
@RequestMapping("/api/student/review")
public class RestStudentReviewController {

    @Resource
    private StudentReviewService studentReviewService;

    @Value("${erp-file-server-url}")
    private String fileServerUrl;

    /////////////////////////////////////////////////////////////////////////////////////////
    ///////////////////////////////  导出待审核学员   ///////////////////////////////////////
    /////////////////////////////////////////////////////////////////////////////////////////

    @ApiOperation(value = "导出待审核学员信息")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "cityCode", value = "城市编号", required = true, dataType = "String"),
            @ApiImplicitParam(name = "driverSchoolId", value = "驾校ID", defaultValue = "0", dataType = "Long"),
            @ApiImplicitParam(name = "searchKey", value = "学员姓名或身份证号", dataType = "String"),
            @ApiImplicitParam(name = "timeType", value = "时间类型(1为创建时间，2为提交时间)", dataType = "String"),
            @ApiImplicitParam(name = "fromTime", value = "开始时间", dataType = "String"),
            @ApiImplicitParam(name = "toTime", value = "结束时间", dataType = "String")

    })
    @GetMapping(GlobalConstant.GATEWAY_IGNORE + "/export")
    public void exportData(HttpServletResponse response, ExportStudentConditionVo conditionVo, String currentUserId) throws Exception {

        if(!StringUtils.isNotEmpty(conditionVo.getCityCode())){
            throw new BizException("请选择导入数据所属城市");
        }

        UserDto userDto = UserUtil.getCurrentUserInfo(currentUserId);
        // 获取导出数据
        List<StudentInfo> studentInfoList = studentReviewService.saveAndGetExportData(conditionVo, userDto.getName());

        // 导出ZIP文件
        exportZip(response, studentInfoList);
    }

    private void exportZip(HttpServletResponse response, List<StudentInfo> studentInfoList) {
        response.setContentType("application/octet-stream");
        response.setHeader("Content-Disposition", "attachment; filename=" + DateUtils.getXXTimeString() + ".zip");
        ZipOutputStream zos = null;
        try {
            zos = new ZipOutputStream(response.getOutputStream());

            ExcelData excelData = getExcelData(studentInfoList);
            // 获取Excel文件流
            HSSFWorkbook excelBook = ExcelUtil.exportExcelForStream(excelData);
            zos.putNextEntry(new ZipEntry("学员基本信息.xls"));
            excelBook.write(zos);

            for (StudentInfo studentData : studentInfoList) {   // 循环把文件流添加到压缩包中
                if(studentData.getListStudentPicture() != null) {
                    for (StudentFileInfo studentFileInfo : studentData.getListStudentPicture()) {
                        zos.putNextEntry(new ZipEntry(studentData.getName()+ "\\" + getFileName(studentFileInfo, studentData.getListStudentPicture()) + ".jpg")) ; //压缩文件名称 设置ZipEntry对象

                        try {
                            String fileUrl = fileServerUrl + "/file/download?id=" + studentFileInfo.getFileId();

                            URL url = new URL(fileUrl);
                            HttpURLConnection conn = (HttpURLConnection)url.openConnection();
                            conn.setRequestMethod("GET");
                            conn.setConnectTimeout(5 * 1000);
                            InputStream inStream = conn.getInputStream();//通过输入流获取图片数据

                            int temp = 0 ;
                            while((temp=inStream.read())!=-1){ // 读取内容
                                zos.write(temp) ;    // 压缩输出
                            }
                            inStream.close() ; // 关闭输入流

                        } catch (Exception ex) {

                        }
                    }
                }
            }

        } catch (Exception e) {
            e.printStackTrace();

        } finally {
            // 关闭流
            try {
                if (null != zos){
                    zos.flush();
                    zos.close();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

    }

    /**
     * 获取文件名，若同类型文件有多个，则增加序号
     * @param studentFileInfo
     * @param studentFileInfoList
     * @return
     */
    private String getFileName(StudentFileInfo studentFileInfo, List<StudentFileInfo> studentFileInfoList) {
        String fileName = "";
        int index = 0;
        for (StudentFileInfo fileInfo : studentFileInfoList) {
            if(studentFileInfo.getType() == fileInfo.getType()) {
                index++;
                if(studentFileInfo.getId() == fileInfo.getId()) {
                    break;
                }
            }
        }
        fileName = studentFileInfo.getType().getDesc();
        if(index > 1) {
            fileName = fileName + "_" + index;
        }
        return fileName;
    }

    /**
     * 封装导出数据
     * @param studentInfoList
     * @return
     */
    private ExcelData getExcelData(List<StudentInfo> studentInfoList) {
        ExcelData excelData = new ExcelData();
        excelData.setFileName(DateUtils.getXXTimeString() + ".xls");
        String[] headArr = {"学员编号", "姓名", "证件号码", "国籍", "性别", "出生日期", "手机号", "邮箱",
                "是否绑定微信号", "微信openid", "暂住证编号", "住所详细地址", "登记住所详细地址",
                "驾校名称", "车型", "学习类型", "报名来源", "报名日期", "备注"};
        excelData.setHead(headArr);
        List<String[]> dataList = new ArrayList<>();
        for (StudentInfo studentItem : studentInfoList) {
            String[] dataArr = new String[headArr.length];
            dataArr[0] = studentItem.getStudentNumber();
            dataArr[1] = studentItem.getName();
            dataArr[2] = studentItem.getCertificatesNumber();
            dataArr[3] = studentItem.getCountry();
            dataArr[4] = studentItem.getSex();
            dataArr[5] = studentItem.getBirthday();
            dataArr[6] = studentItem.getPhone();
            dataArr[7] = studentItem.getEmail();
            dataArr[8] = studentItem.getIsBindingWechat().getDesc();
            dataArr[9] = studentItem.getWechatOpenid();
            dataArr[10] = studentItem.getStayAddreeNumber();
            dataArr[11] = studentItem.getAddressDetailed();
            dataArr[12] = studentItem.getRegisteredResidence();
            dataArr[13] = studentItem.getDriversName();
            dataArr[14] = studentItem.getCarName();
            dataArr[15] = studentItem.getStatus().getDesc();
            dataArr[16] = studentItem.getRegisteredSource();
            dataArr[17] = DateUtils.getTimeString(studentItem.getRegisteredTime());
            dataArr[18] = studentItem.getReason();
            dataList.add(dataArr);
        }
        excelData.setData(dataList);
        return excelData;
    }


    @ApiOperation(value = "导出数据回写")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "recordId", value = "导出记录ID", required = true, dataType = "String"),
    })
    @PostMapping("/backWriteExportResult")
    public ResultEntity backWriteExportResult(@RequestParam("file") MultipartFile file, @RequestParam(name = "recordId") Long recordId) throws Exception {

        if(file == null || file.getSize() == 0){
            return ResultEntity.failed("文件不能为空");
        }
        if(recordId == null || recordId == 0) {
            return ResultEntity.failed("无效的导出记录ID");
        }
        InputStream inputStream = file.getInputStream();
        List<List<String>> excelData = ExcelUtil.importExcel(inputStream,file.getOriginalFilename(), 2);
        inputStream.close();

        // 保存导入数据
        studentReviewService.saveImportData(excelData, recordId);
        return ResultEntity.success("导入成功");
    }

    @ApiOperation(value = "删除导出记录")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "ids", value = "导出记录ID：id1,id2,id3", defaultValue = "", required = true, dataType = "String", paramType = "Query")
    })
    @GetMapping("/deleteExportRecord")
    public ResultEntity deleteExportRecord(String ids) throws Exception {
        studentReviewService.deleteExportRecord(ids);
        return ResultEntity.success("删除成功");
    }

    @ApiOperation(value = "分页查询导出记录")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "pageIndex", value = "当前页", required = true, dataType = "Integer", defaultValue = "1", paramType = "Query"),
            @ApiImplicitParam(name = "pageSize", value = "每页大小", required = true, dataType = "Integer", defaultValue = "20", paramType = "Query"),
            @ApiImplicitParam(name = "serialNumber", value = "流水号", dataType = "String", paramType = "Query"),
            @ApiImplicitParam(name = "fromTime", value = "开始时间", dataType = "String", paramType = "Query"),
            @ApiImplicitParam(name = "toTime", value = "结束时间", dataType = "String", paramType = "Query"),
            @ApiImplicitParam(name = "provinceCode", value = "操作省Code", dataType = "Long", paramType = "Query"),
            @ApiImplicitParam(name = "cityCode", value = "操作城市Code", dataType = "Long", paramType = "Query")
    })
    @GetMapping("/listExportRecord")
    public ResultEntity<PageBean<ExportRecord>> listExportRecord(ReviewConditionVo params) {
        return ResultEntity.success(studentReviewService.findExportRecordByPage(params));
    }

    @ApiOperation(value = "分页查询导出记录明细")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "pageIndex", value = "当前页", required = true, dataType = "Integer", defaultValue = "1", paramType = "Query"),
            @ApiImplicitParam(name = "pageSize", value = "每页大小", required = true, dataType = "Integer", defaultValue = "20", paramType = "Query"),
            @ApiImplicitParam(name = "recordId", value = "记录Id", required = true, dataType = "Long", defaultValue = "0", paramType = "Query"),
            @ApiImplicitParam(name = "searchKey", value = "学员姓名或证件号码", dataType = "String", paramType = "Query"),
            @ApiImplicitParam(name = "fileType", value = "文件类别：all:所有;normal:无文件; sfz:身份证头像;mqb:互联网面签协议;cxjs:初学驾驶申请表;zjjs:增驾驾驶申请表;zw:指纹;ljz:原驾驶证;zzz:制证照;pxjl:培训记录;xszm:学时证明;zzpermit:居住证照片;idz:身份证正面;idf:身份证反面;healthForm:体检表;scenePhotos:现场照片;zjzo:证件照;tjbtp:提交表图片;sfzdzz:身份证电子照片;zcbmqz:注册表面签照", dataType = "String", defaultValue = "0", paramType = "Query"),
            @ApiImplicitParam(name = "exportStatus", value = "导出状态：all:所有；exp:导出；imp:导入", dataType = "String", defaultValue = "0", paramType = "Query")
    })
    @GetMapping("/listExportDetail")
    public ResultEntity<PageBean<ExportRecordDetail>> listExportDetail(ReviewConditionVo params) {
        return ResultEntity.success(studentReviewService.findExportDetailByPage(params));
    }

    @ApiOperation(value = "查询导出统计信息")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "dataId", value = "导入导出记录ID", required = true, dataType = "Long", paramType = "Query")
    })
    @GetMapping("/recordStatistics")
    public ResultEntity<List<ExportRecordStatistics>> recordStatistics(Long dataId){
        List<ExportRecordStatistics> statisticsList = studentReviewService.getExportStatistics(dataId);
        return ResultEntity.success(statisticsList);
    }


    /////////////////////////////////////////////////////////////////////////////////////////
    ///////////////////////////////  审核结果导入     ///////////////////////////////////////
    /////////////////////////////////////////////////////////////////////////////////////////


    @ApiOperation(value = "导入学员信息审核结果")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "cityCode", value = "城市编号", required = true, dataType = "String"),
    })
    @PostMapping("/importCheckResult")
    public ResultEntity importData(@RequestParam("file") MultipartFile file, @RequestParam(name = "cityCode")String cityCode, String currentUserId) throws Exception {

        if(!StringUtils.isNotEmpty(cityCode)){
            return ResultEntity.failed("请选择导入数据所属城市");
        }
        if(file == null || file.getSize() == 0){
            return ResultEntity.failed("文件不能为空");
        }
        UserDto userDto = UserUtil.getCurrentUserInfo(currentUserId);

        InputStream inputStream = file.getInputStream();
        List<List<String>> excelData = ExcelUtil.importExcel(inputStream,file.getOriginalFilename(), 5);
        inputStream.close();

        // 保存导入数据
        studentReviewService.saveImportCheckResultData(excelData, cityCode, userDto.getName());
//        studentReviewService.saveImportCheckResultData(excelData, cityCode, "王老师");
        return ResultEntity.success("导入成功");
    }

    @ApiOperation(value = "删除导入记录")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "ids", value = "导入记录ID：id1,id2,id3", defaultValue = "", required = true, dataType = "String", paramType = "Query")
    })
    @GetMapping("/deleteImportRecord")
    public ResultEntity deleteImportRecord(String ids) throws Exception {
        studentReviewService.deleteImportRecord(ids);
        return ResultEntity.success("删除成功");
    }

    @ApiOperation(value = "分页查询审核结果导入记录")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "pageIndex", value = "当前页", required = true, dataType = "Integer", defaultValue = "1", paramType = "Query"),
            @ApiImplicitParam(name = "pageSize", value = "每页大小", required = true, dataType = "Integer", defaultValue = "20", paramType = "Query"),
            @ApiImplicitParam(name = "serialNumber", value = "流水号", dataType = "String", paramType = "Query"),
            @ApiImplicitParam(name = "fromTime", value = "开始时间", dataType = "String", paramType = "Query"),
            @ApiImplicitParam(name = "toTime", value = "结束时间", dataType = "String", paramType = "Query"),
            @ApiImplicitParam(name = "provinceCode", value = "操作省Code", dataType = "Long", paramType = "Query"),
            @ApiImplicitParam(name = "cityCode", value = "操作城市Code", dataType = "Long", paramType = "Query")
    })
    @GetMapping("/listImportRecord")
    public ResultEntity<PageBean<CheckResultImportRecord>> listImportRecord(ReviewConditionVo params) {
        return ResultEntity.success(studentReviewService.findImportRecordByPage(params));
    }

    @ApiOperation(value = "分页查询导入记录明细")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "pageIndex", value = "当前页", required = true, dataType = "Integer", defaultValue = "1", paramType = "Query"),
            @ApiImplicitParam(name = "pageSize", value = "每页大小", required = true, dataType = "Integer", defaultValue = "20", paramType = "Query"),
            @ApiImplicitParam(name = "timeType", value = "时间类型：1为申请时间；2为受理时间", dataType = "Integer", paramType = "Query"),
            @ApiImplicitParam(name = "fromTime", value = "开始时间", dataType = "String", paramType = "Query"),
            @ApiImplicitParam(name = "toTime", value = "结束时间", dataType = "String", paramType = "Query"),
            @ApiImplicitParam(name = "searchKey", value = "学员姓名或证件号码", dataType = "String", paramType = "Query")
    })
    @GetMapping("/listImportDetail")
    public ResultEntity<PageBean<CheckResultImportRecordDetail>> listImportDetail(ReviewConditionVo params) {
        return ResultEntity.success(studentReviewService.findImportDetailByPage(params));
    }

}
